#ifndef BASEQUEUEE_H_
#define BASEQUEUEE_H_

#include <vector>
#include <string>

#include "./../error.h"

namespace queue
{

	template <class T>
	class BaseQueueE
	{
	public:
	
		BaseQueueE( const unsigned int );
	
		virtual 
		~BaseQueueE();
	
		void
		clear();
	
		void
		push (const T);
	
		void
		pop();
	
		T
		first() const;

		bool
		empty() const;
	
		bool
		full() const;

	protected:
	
		void
		throwException( std::string, const unsigned short int );
	
		std::vector<T>
		queue;
		
		//era pra ser iterator... num deu tempo...
		unsigned int
		firstNode;

		unsigned int
		lastNode;
	};

}

/**************************************
 *
 *        Implementations
 *
 * ************************************/

//Public methods

template<class T>
queue::BaseQueueE<T>::BaseQueueE ( const unsigned int _maxNodes )
{
	this->queue.resize(_maxNodes);
}

template<class T>
queue::BaseQueueE<T>::~BaseQueueE ()
{
	this->queue.clear();
}

template<class T> void
queue::BaseQueueE<T>::clear()
{
	this->queue.clear();
}

template<class T> void
queue::BaseQueueE<T>::push ( const T _info)
{
	if (! this->full() )
	{
		if ( this->lastNode == this->queue.size() - 1 )
		{
			this->queue.at(0) = _info;
			this->lastNode = 0;
		}
		else
		{
			this->queue.at( lastNode + 1 ) = _info;
			this->lastNode++;
		}
	}
	else
	{
		this->throwException("The queue is already full!", 4);
	}
}

template<class T> void
queue::BaseQueueE<T>::pop()
{
	if (! this->empty() )
	{
		if (this->firstNode == this->queue.size() - 1 )
		{
			this->firstNode == 0;
		}
		else
		{
			this->firstNode++;
		}
	}
	else
	{
		this->throwException("Queue already empty!");
	}
}

template<class T> T
queue::BaseQueueE<T>::first() const
{
	return this->queue.at(firstNode);
}

template<class T> bool
queue::BaseQueueE<T>::empty() const
{
	if( this->firstNode == this->lastNode)
		return true;
	return false;
}

template<class T> bool
queue::BaseQueueE<T>::full() const
{
	if ( (this->queue.size() - this->firstNode) + this->lastNode == this->queue.size() - 1 )
		return true;
	return false;
}

#endif /*BASEQUEUEE_H_*/
